package cn.jisol.ngame.actions;

import cn.jisol.ngame.actions.core.NAction;
import cn.jisol.ngame.actions.core.NActionEnum;
import cn.jisol.ngame.actions.core.NActionMethod;
import cn.jisol.ngame.client.NClient;
import cn.jisol.ngame.proto.JNSyncMessage;
import cn.jisol.ngame.proto.NActionMessage;
import cn.jisol.ngame.sync.frame.JNSyncFrame;
import cn.jisol.ngame.sync.state.JNSyncStateDefault;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@NAction
public class SystemAction {

    //帧同步类
    public static JNSyncFrame frame;
    //状态同步
    public static JNSyncStateDefault state;
    public static Map<String, NClient> clients;

    @NActionMethod(NActionEnum.PING)
    public static void Ping(){
        System.out.println("PING");
    }


    @NActionMethod(NActionEnum.ServerClientConnect)
    public static void ServerClientConnect(NClient client,Map<String, NClient> clients) {

        //发送其他客户端
        clients.values().forEach(nClient -> {
            nClient.invoke(NActionEnum.ServerClientConnect, JNSyncMessage.JNClientConnect.newBuilder().setClientId(client.getId()).build());
        });

    }

    @NActionMethod(NActionEnum.ServerClientDisconnect)
    public static void ServerClientDisconnect(NClient client,Map<String, NClient> clients) {

        //发送其他客户端
        clients.values().forEach(nClient -> {
            nClient.invoke(NActionEnum.ServerClientDisconnect, JNSyncMessage.JNClientDisconnect.newBuilder().setClientId(client.getId()).build());
        });

    }

    @NActionMethod(NActionEnum.NActionDemo)
    public static void  NActionDemo(NActionMessage.NActionDemo nActionDemo, NClient client) {
        System.out.println("["+client.getId()+"]NActionDemo : "+nActionDemo.getMessage());
        client.invoke(NActionEnum.NActionDemo2,NActionMessage.NActionDemo.newBuilder().setMessage("Hello Message").build());
    }

    //开启帧同步
    @NActionMethod(NActionEnum.NSyncFrameStart)
    public static void NSyncFrameStart(Map<String, NClient> clients){
        if(Objects.nonNull(SystemAction.frame)) return;
        System.out.println("NSyncFrameStart 开启帧同步 : "+clients.size());
        SystemAction.frame = new JNSyncFrame(66);
        SystemAction.clients = clients;
        //绑定事件
        SystemAction.frame.Bind(SystemAction::JNFrameBack);
        SystemAction.frame.Start();//开始同步
    }

    //开启状态同步
    @NActionMethod(NActionEnum.NSyncStateStartRequest)
    public static void NSyncStateStart(Map<String, NClient> clients){
        if(Objects.nonNull(SystemAction.state)) return;
        SystemAction.state = new JNSyncStateDefault();
        SystemAction.state.Bind(SystemAction::JNStateBack);
        SystemAction.state.BindAll(SystemAction::JNStateBackAll);
    }


    //接受帧数据
    @NActionMethod(NActionEnum.NSyncFrameInput)
    public static void NSyncFrameInput(JNSyncMessage.JNFrameInputs input){
        if(Objects.nonNull(SystemAction.frame)){
            //收集
            SystemAction.frame.addInputs(input.getInputsList());
        }
    }

    //接受状态数据更新
    @NActionMethod(NActionEnum.NSyncStateDataUpdateRequest)
    public static void NSyncStateDataUpdate(JNSyncMessage.JNStateItemData data){
        if(Objects.nonNull(SystemAction.state)){
            //更新状态
            SystemAction.state.StateUpdate(data);
        }
    }

    //接受全量状态数据更新
    @NActionMethod(NActionEnum.NSyncStateAllUpdateRequest)
    public static void NSyncStateAllUpdate(JNSyncMessage.JNStateAllData data){
        if(Objects.nonNull(SystemAction.state)){

            HashMap<Integer,JNSyncMessage.JNStateItemData> allData = new HashMap<>();
            data.getDataList().forEach(child -> allData.put(child.getNetID(),child));

            //更新状态
            SystemAction.state.AllStateUpdate(allData);
        }
    }

    //重置帧同步
    @NActionMethod(NActionEnum.NSyncFrameReset)
    public static void NSyncFrameReset(Map<String, NClient> clients){
        System.out.println("NSyncFrameReset 重置帧同步 : "+clients.size());
        if(Objects.nonNull(SystemAction.frame)){
            SystemAction.frame.End();
            SystemAction.frame = null;
        }
        SystemAction.NSyncFrameStart(clients);
    }

    //关闭帧同步
    public static void NSyncFrameEnd(){
        if(Objects.nonNull(SystemAction.frame)){
            SystemAction.frame.End();
            SystemAction.frame = null;
        }
        if(Objects.nonNull(SystemAction.state)){
            SystemAction.state = null;
        }
    }

    //帧回调事件
    private static void JNFrameBack(JNSyncMessage.JNFrameInfo info) {

        //向所有客户端发送帧同步数据
        SystemAction.clients.values().forEach(client -> {
            client.invoke(NActionEnum.NSyncFrameBack,info);
        });

    }

    //状态回调
    private static void JNStateBack(JNSyncMessage.JNStateItemData data) {

        //向所有客户端发送帧同步数据
        SystemAction.clients.values().forEach(client -> {
            client.invoke(NActionEnum.NSyncStateBackResponse,data);
        });

    }

    //状态全量回调
    private static void JNStateBackAll(JNSyncMessage.JNStateAllData data) {
        //向所有客户端发送帧同步数据
        SystemAction.clients.values().forEach(client -> {
            client.invoke(NActionEnum.NSyncStateAllBackResponse,data);
        });
    }


}
